package service

import (
	"errors"
	"user/domain/model"
	"user/domain/repository"

	"golang.org/x/crypto/bcrypt"
)

type IUserService interface {
	AddUser(*model.User) (int64, error)
	DeleteUser(int64) error
	UpdateUser(*model.User, bool) error
	FindUserByName(string) (*model.User, error)
	CheckPwd(string, string) (bool, error)
}

type UserService struct {
	userRepository repository.IUserRepository
}

func (u *UserService) AddUser(user *model.User) (int64, error) {
	hashPassword, err := GeneratePassword(user.Password)
	if err != nil {
		return 0, err
	}
	user.Password = string(hashPassword)
	return u.userRepository.Createuser(user)
}

func (u *UserService) DeleteUser(userID int64) error {
	return u.userRepository.DeleteUserByID(userID)
}

func (u *UserService) UpdateUser(user *model.User, isChangePwd bool) error {
	if isChangePwd {
		hashPassword, err := GeneratePassword(user.Password)
		if err != nil {
			return err
		}
		user.Password = string(hashPassword)
	}
	return u.userRepository.UpdateUser(user)
}

func (u *UserService) FindUserByName(username string) (*model.User, error) {
	return u.userRepository.FindUserByName(username)
}

func (u *UserService) CheckPwd(username, password string) (bool, error) {
	user, err := u.userRepository.FindUserByName(username)
	if err != nil {
		return false, err
	}
	return ValidatePassword(password, user.Password)
}

func NewUserService(userRepository repository.IUserRepository) IUserService {
	return &UserService{userRepository}
}

func GeneratePassword(password string) ([]byte, error) {
	return bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
}

func ValidatePassword(password, hashed string) (bool, error) {
	if err := bcrypt.CompareHashAndPassword([]byte(hashed), []byte(password)); err != nil {
		return false, errors.New("密码不对")
	}
	return true, nil
}
